nice_things/macros/nice_build.macro.sh
These macros are not exactly part of the framework's public API. They are embedded directly in nice_build.sh, the template renderer used by the nice_things framework. Since these names are global, they are accessible in macro context at any time during the build process.
The functions documented in this page are not the only ones available during build. Almost all functions in the framework are imported globally in nice_build and can be invoked in macro context. The main exception are classes which are omitted, except for a few methods being used by the build system, like Array, Array_get, Array_length, Array_push; Map, Map_get, Map_set; PipeStatus, catch, try.
import
Since 0.3.0 · Source
Synopsisimport ["{ <name> [as <alias>], … }" from] <module>
Configuration
name=<package_name>
namespace=<package_namespace>
Description
Import functions and read-only variables from modules. Several modules can be imported in a single invocation, each with optional aliases for the names being imported.
Names being aliased by this function must have been published by the imported module using the public macro. Importing specific names can be omitted, in which case a module is imported just for its global names or side-effects.
Imported modules and each specific alias are rendered only once, on the first time they appear. Which means this macro may not print anything at the point of use if <module> has already been imported before as a dependency of another module.
The import function performs automatic namespace substitution on the imported modules. The namespace configuration property indicates the per-package namespace, and is optional. If omitted, it will fall back to using the package name as namespace. The name configuration property is itself also optional, falling back to using the directory name as package name.
Options
–
Operands
<name>: A public name to be aliased.<alias>: An optional different alias to give<name>in this module's context.<module>: A module specifier.
Stdin
–
Stdout
The imported modules are printed, each followed by its aliases if specified.
Stderr
–
Exit status
0: Successful completion.>0: Unexpected error (abort).
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
#{{{
# Import a module only for it's side-effects without aliasing any names
import ./src/module.sh
# Import functions from a module to global scope
import "{ function1, function2 }" from ./src/module.sh
# Import readonly variable from a module to global scope
import "{ readonly:var_name }" from ./src/module.sh
# Import functions/readonly variables giving them namespaced aliases in the current module's scope
import "{
readonly:var_name as NS__var_name,
function1 as NS__function1,
function2 as NS__function2
}" from ./src/module.sh
# Import logging functions from nice_things to global scope
import \
"{ abort }" from nice_things/log/abort.sh \
"{ log_error, log_warn, log_info, log_debug, log_trace, log_is_level }" from nice_things/log/log.sh
#}}}
include
Since 0.3.0 · Source
Synopsisinclude <module>…
Configuration
–
Description
Render a module once. Do nothing when trying to render the same <module> again.
Unlike the import macro, this function does not perform namespace substitution, and cannot alias names. It is most similar to the generic render macro, with the main difference being that it will not render the same <module> twice.
When importing source-code modules, you will almost always want to use the import macro instead. include and render are more appropriate for rendering other types of templates, usually with data instead of code, or code in another language instead of shell script.
Options
–
Operands<module>: A module specifier.
Stdin
–
Stdout
The imported modules are printed.
Stderr
–
Exit status
0: Successful completion.>0: Unexpected error (abort).
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
#{{{
# Render a template if not included yet
include ./src/file.template
#}}}
package_conf_get_bool
Since 0.3.0 · Source
Synopsispackage_conf_get_bool [-o | -r] <section> <property>
Configuration
–
Description
Read a boolean property from nice_package.conf.
The value of boolean properties must be true or false, otherwise the build is aborted with an error.
For a full explanation of all options and arguments, check the description of the package_conf_get_string macro.
Options
-o: Let the program configuration (./nice_package.conf), if present, override the configuration from the current package.-r: Read the program configuration (./nice_package.conf) instead of the configuration for the current package. Note that this mode will abort if the configuration file does not exist.
Operands
<section>: Name of the section, including the square brackets.<property>: Name of the property.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Property istrue.1: Property isfalse.>1: Unexpected error (abort).
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
NS__no_color=#{{{
# If config property is set to true, set this variable
if package_conf_get_bool module no_color; then
printf 1
fi
#}}}
package_conf_get_string
Since 0.3.0 · Source
Synopsispackage_conf_get_string [-o | -r] <out_var> <section> <property>
Configuration
–
Description
Read a string property from nice_package.conf.
By default this macro reads the configuration file for the package the current module is part of. That is, the configuration for the module where it is invoked. The option flags -o and -r can be used to change that behavior, letting the configuration for the program being built override the module configuration, or reading only the program configuration, respectively.
Besides the name of a section in the configuration file, the <section> argument also accepts two special literal values:
module: A dynamic section named after the module identifier of the form[module:path/to/module.sh].package: A dynamic section named after the package of the form[package:package_name].
When using the dynamic sections, the options -o and -r are ignored, they always behave as if the -o option is set.
The dynamic section format is the recommended way to configure public modules in library packages. They allow configuration either at the package or at the module level and protect against name collisions. Here is an example configuration from the nice_things framework:
[package:nice_things]
# Value to be assigned to the IFS variable in strict_mode; accepts printf-style escape sequences
strict_mode_ifs=\037
[module:nice_things/log/log.sh]
# If true, info logs will be preceded by their level name (INFO), like the other levels
named_info=false
# If true, runtime config will default to 'no-color'
no_color=false
# Name of the variable used for runtime configuration
variable=LOG_LEVEL
In framework code those can be read as:
#{{{
# Read package configuration
# Note how `package` must be explicitly set for this to work in public modules
package=nice_things package_conf_get_string out_var package strict_mode_ifs
#}}}
#{{{
# Read configuration specific to the current module
package_conf_get_string out_var module variable
#}}}
Options
-o: Let the program configuration (./nice_package.conf), if present, override the configuration from the current package.-r: Read the program configuration (./nice_package.conf) instead of the configuration for the current package.
Operands
<out_var>: Output variable; the result will be written to this variable.<section>: Name of the section, including the square brackets.<property>: Name of the property.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.1:<property>not found.>1: Unexpected error (abort).21: Invalid property value in config file. Expected string but found array.
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
NS__param_level=${1:-"{{{" package_conf_get_string value module variable && printf '${%s-}' "$value" "}}}"}
package_conf_print_string
Since 0.3.0 · Source
Synopsispackage_conf_print_string [-o | -r] <section> <property>
Configuration
–
Description
Print the value of a string property from nice_package.conf.
For a full explanation of all options and arguments, check the description of the package_conf_get_string macro.
Options
-o: Let the program configuration (./nice_package.conf), if present, override the configuration from the current package.-r: Read the program configuration (./nice_package.conf) instead of the configuration for the current package.
Operands
<section>: Name of the section, including the square brackets.<property>: Name of the property.
Stdin
–
Stdout
The value of the property is printed.
Stderr
–
Exit status
0: Successful completion.1:<property>not found.>1: Unexpected error (abort).21: Invalid property value in config file. Expected string but found array.
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
# Print the module specifier and package version for the current module
# {{{$module}}} {{{ package_conf_print_string "[]" version }}}
package_get
Since 0.3.0 · Source
Synopsispackage_get <package> [<out_var> <property>]…
Configuration
–
Description
Read package properties.
The list of properties a package has are:
name: Name of the package; the value of thenameproperty innice_package.confif specified, or fall back todir_name(this function retrieves a package by name, so this property is redundant).namespace: The package namespace; the value of thenamespaceproperty innice_package.confif specified, or fall back to the name of the package.dir_name: The name of the root directory of the package.path: Relative path to the root directory of the package.config_file: Relative path to the package's configuration filenice_package.conf, if it exists; null otherwise.config: A reference to the package'sConfigobject, if it exists; null otherwise.
Note
This function was made for internal use in
nice_build. Many other macros exist to read a package's configuration, so look at them first:package_conf_get_bool,package_conf_get_string,package_conf_print_string.
It is unlikely that application code will need to access a package's data directly using this macro.
Options
–
Operands
<package>: Name of package.<out_var>: Output variable; the result will be written to this variable.<property>: Property to retrieve.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.1: One or more<property>does not exist in the package.3:<package>not found.
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
#{{{
package_get "$package" package_path path || exit
log_debug "The package '${package}' is at path '${package_path}'"
#}}}
public
Since 0.3.0 · Source
Synopsispublic [readonly:]<name>…
Configuration
–
Description
Publish a <name> from the current module.
A <name> can be a namespaced function (NS__function_name) or read-only variable (readonly NS__var_name), by prepending the readonly: prefix to the public declaration. Names must be public to be imported by dependent modules with the import macro.
Warning
The
publicdeclaration should always be the first macro at the top of a module. To prevent errors on circular dependencies, theimportmacro must always come after thepublicdeclaration.
Note that the complete names are used in the public declaration including their namespaces, but the modules importing them omit the namespace as that is automatically added by the import macro. Only namespace'd names can be declared public; there is no reason to publish non-namespace'd names as they are already global.
Names ending in an underscore character (_) are private and cannot be published. Use this mechanism to explicitly mark private names to prevent accidentally leaking them on the public interface.
Options
–
Operands<name>: A namespaced function or read-only variable in the current module.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.>0: Unexpected error (abort).
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
#{{{
public \
readonly:NS__var_name \
NS__some_function \
NS__another_function
#}}}
render
Since 0.3.0 · Source
Synopsisrender [<module>…]
Configuration
–
Description
Render a template to stdout. Templates are read from <module> arguments. If no arguments are provided, the template is read from stdin.
For details on the template format, refer to the documentation of the template engine at https://codeberg.org/nice_things/template.sh
Note
If you want to print the contents of a file but do not need to render it as a template, you can simply call the
catfunction in macro context.
Options
–
Operands<module>: A module specifier.
Stdin
Only read if no arguments are provided.
Stdout
The rendered template is printed.
Stderr
–
Exit status
0: Successful completion.>0: Unexpected error (abort).
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
#{{{
# Render a template in the current position
render ./src/file.template
#}}}
use_macro
Since 0.3.0 · Source
Synopsisuse_macro <macro>…
Configuration
–
Description
Execute macros in the current context.
Application macros are automatically executed from the file at ./src/main.macro.sh, and macros from the nice_things framework are also executed automatically. If another dependency provides public macros for application use, you will have to execute them manually using this function. Normally you will invoke the use_macro function in the application's ./src/main.macro.sh file to load macros before rendering starts.
Options
–
Operands<macro>: A module specifier pointing to a macro file.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.>0: Unexpected error (abort).
Abort
Any failure will abort the build process. No runtime abort is added.
Usage examples
use_macro package/path/to/file.macro.sh
readonly:module
Since 0.3.0 · Source
Synopsis{{{$module}}}
Configuration
–
Description
Module identifier of the current module.
Options
–
Operands
–
Stdin
–
Stdout
–
Stderr
–
Exit status
–
Abort
–
Usage examples
# Module: {{{$module}}}
readonly:module_path
Since 0.3.0 · Source
Synopsis{{{$module_path}}}
Configuration
–
Description
Relative path to the current module.
Options
–
Operands
–
Stdin
–
Stdout
–
Stderr
–
Exit status
–
Abort
–
Usage examples
# Module path: {{{$module_path}}}
readonly:ns
Since 0.3.0 · Source
Synopsis{{{$ns}}}
Configuration
–
Description
Namespace of the current module.
Options
–
Operands
–
Stdin
–
Stdout
–
Stderr
–
Exit status
–
Abort
–
Usage examples
# Module namespace: {{{$ns}}}
readonly:package
Since 0.3.0 · Source
Synopsis{{{$package}}}
Configuration
–
Description
Name of the package the current module belongs to.
Options
–
Operands
–
Stdin
–
Stdout
–
Stderr
–
Exit status
–
Abort
–
Usage examples
# Package: {{{$package}}}
readonly:root_package
Since 0.3.0 · Source
Synopsis{{{$root_package}}}
Configuration
–
Description
Name of the root package. This is the program being built.
Options
–
Operands
–
Stdin
–
Stdout
–
Stderr
–
Exit status
–
Abort
–
Usage examples
# Program: {{{$root_package}}}